<template>
  <div class="file-upload-component">
    <el-dialog 
      :title="title" 
      :visible.sync="dialogVisible" 
      :width="width" 
      @close="handleDialogClose"
      @open="handleDialogOpen"
    >
      <div class="upload-container">
        <el-upload
          class="upload-dragger"
          drag
          :action="uploadAction"
          :file-list="fileList"
          :on-success="handleUploadSuccess"
          :on-error="handleUploadError"
          :on-change="handleFileChange"
          :on-remove="handleFileRemove"
          :before-upload="beforeUpload"
          :auto-upload="autoUpload"
          :multiple="multiple"
          :accept="accept"
          ref="upload"
        >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">
            请将{{ fileTypeText }}拖到此处，或<em>点击上传</em>
          </div>
          <div class="el-upload__tip" slot="tip" v-if="showTip">
            <div>{{ tipText }}</div>
          </div>
        </el-upload>
        
        <!-- 模板下载 -->
        <div v-if="showTemplate && templateUrl" class="template-download">
          <div class="template-info">
            <span class="template-label">下载模板：</span>
            <el-button type="text" @click="downloadTemplate" class="template-button">
              {{ templateName }}
            </el-button>
          </div>
        </div>

        <!-- 文件列表 -->
        <div v-if="showFileList && fileList.length > 0" class="file-list-section">
          <h4 class="section-title">{{ fileListTitle }}</h4>
          <el-table :data="fileList" border size="mini" style="margin-top: 10px;">
            <el-table-column align="center" label="序号" type="index" width="60">
            </el-table-column>
            <el-table-column align="center" label="文件名称" prop="name" min-width="200">
              <template slot-scope="scope">
                <span :title="scope.row.name">{{ scope.row.name }}</span>
                <span v-if="scope.row.size" style="color: #999; font-size: 12px;">
                  ({{ formatFileSize(scope.row.size) }})
                </span>
              </template>
            </el-table-column>
            <el-table-column align="center" label="文件类型" width="100">
              <template slot-scope="scope">
                <span>{{ getFileType(scope.row.name) }}</span>
              </template>
            </el-table-column>
            <el-table-column align="center" label="状态" width="100" v-if="showStatus">
              <template slot-scope="scope">
                <el-tag :type="getStatusType(scope.row.status)" size="mini">
                  {{ getStatusText(scope.row.status) }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column align="center" label="操作" width="120" v-if="showActions">
              <template slot-scope="scope">
                <el-button 
                  v-if="showPreview" 
                  type="text" 
                  size="mini" 
                  @click="handlePreview(scope.row)"
                >预览</el-button>
                <el-button 
                  type="text" 
                  size="mini" 
                  style="color: #f56c6c;" 
                  @click="handleDelete(scope.$index)"
                >删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
      
      <div slot="footer" class="dialog-footer">
        <el-button @click="handleCancel">取 消</el-button>
        <el-button type="primary" @click="handleConfirm" :loading="confirmLoading">
          {{ confirmText }}
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'FileUpload',
  
  props: {
    // 弹窗标题
    title: {
      type: String,
      default: '上传文件'
    },
    // 弹窗宽度
    width: {
      type: String,
      default: '800px'
    },
    // 上传地址
    uploadAction: {
      type: String,
      default: '/api/upload'
    },
    // 是否自动上传
    autoUpload: {
      type: Boolean,
      default: false
    },
    // 是否支持多选
    multiple: {
      type: Boolean,
      default: true
    },
    // 接受的文件类型
    accept: {
      type: String,
      default: '.doc,.docx,.xls,.xlsx,.pdf,.txt,.jpg,.jpeg,.png,.gif'
    },
    // 文件类型文本描述
    fileTypeText: {
      type: String,
      default: '附件'
    },
    // 文件大小限制（MB）
    maxSize: {
      type: Number,
      default: 10
    },
    // 是否显示提示
    showTip: {
      type: Boolean,
      default: true
    },
    // 提示文本
    tipText: {
      type: String,
      default: '只能上传jpg/png/gif/pdf/doc/docx/xls/xlsx文件，且不超过10MB'
    },
    // 是否显示模板下载
    showTemplate: {
      type: Boolean,
      default: false
    },
    // 模板名称
    templateName: {
      type: String,
      default: '模板文件'
    },
    // 下载模板地址
    templateUrl: {
      type: String,
      default: ''
    },
    // 是否显示文件列表
    showFileList: {
      type: Boolean,
      default: true
    },
    // 文件列表标题
    fileListTitle: {
      type: String,
      default: '文件列表'
    },
    // 是否显示状态列
    showStatus: {
      type: Boolean,
      default: false
    },
    // 是否显示操作列
    showActions: {
      type: Boolean,
      default: true
    },
    // 是否显示预览按钮
    showPreview: {
      type: Boolean,
      default: true
    },
    // 确认按钮文本
    confirmText: {
      type: String,
      default: '确定'
    },
    // 外部控制弹窗显示
    visible: {
      type: Boolean,
      default: false
    }
  },

  data() {
    return {
      dialogVisible: false,
      fileList: [],
      confirmLoading: false
    };
  },

  watch: {
    visible: {
      handler(newVal) {
        this.dialogVisible = newVal;
      },
      immediate: true
    },
    dialogVisible(newVal) {
      this.$emit('update:visible', newVal);
    }
  },

  methods: {
    // 弹窗打开
    handleDialogOpen() {
      this.$emit('open');
    },
    // 弹窗关闭
    handleDialogClose() {
      this.fileList = [];
      if (this.$refs.upload) {
        this.$refs.upload.clearFiles();
      }
      this.$emit('close');
    },
    // 上传前验证
    beforeUpload(file) {
      // 文件类型验证
      const acceptTypes = this.accept.split(',').map(type => type.trim());
      const fileExt = '.' + file.name.split('.').pop().toLowerCase();
      
      if (!acceptTypes.includes(fileExt)) {
        this.$message.error(`不支持 ${fileExt} 格式的文件！`);
        return false;
      }
      
      // 文件大小验证
      const isLtMaxSize = file.size / 1024 / 1024 < this.maxSize;
      if (!isLtMaxSize) {
        this.$message.error(`上传文件大小不能超过 ${this.maxSize}MB!`);
        return false;
      }
      
      this.$emit('before-upload', file);
      return true;
    },
    // 文件选择变化
    handleFileChange(file, fileList) {
      this.fileList = fileList;
      this.$emit('file-change', file, fileList);
    },
    // 文件移除
    handleFileRemove(file, fileList) {
      this.fileList = fileList;
      this.$emit('file-remove', file, fileList);
    },
    // 上传成功
    handleUploadSuccess(response, file, fileList) {
      this.$message.success('文件上传成功');
      this.$emit('upload-success', response, file, fileList);
    },
    // 上传失败
    handleUploadError(err, file, fileList) {
      this.$message.error('文件上传失败');
      this.$emit('upload-error', err, file, fileList);
    },
    // 预览文件
    handlePreview(file) {
      this.$emit('preview', file);
    },
    // 删除文件
    handleDelete(index) {
      this.$confirm('确认删除该文件？', '删除提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.fileList.splice(index, 1);
        this.$message.success('删除成功');
        this.$emit('delete', index);
      }).catch(() => {
        this.$message.info('已取消删除');
      });
    },
    // 下载模板
    downloadTemplate() {
      if (this.templateUrl) {
        // 如果有模板URL，直接下载
        const link = document.createElement('a');
        link.href = this.templateUrl;
        link.download = this.templateName;
        link.click();
        this.$message.success('模板下载中...');
      } else {
        // 否则触发事件，让父组件处理
        this.$emit('download-template');
      }
    },
    // 取消
    handleCancel() {
      this.dialogVisible = false;
    },
    // 确认
    handleConfirm() {
      this.$emit('confirm', this.fileList);
    },
    // 获取文件类型
    getFileType(fileName) {
      const ext = fileName.split('.').pop().toLowerCase();
      switch (ext) {
        case 'pdf':
          return 'PDF';
        case 'doc':
        case 'docx':
          return 'Word';
        case 'xls':
        case 'xlsx':
          return 'Excel';
        case 'jpg':
        case 'jpeg':
        case 'png':
        case 'gif':
          return '图片';
        default:
          return '其他';
      }
    },
    // 格式化文件大小
    formatFileSize(bytes) {
      if (bytes === 0) return '0 B';
      const k = 1024;
      const sizes = ['B', 'KB', 'MB', 'GB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
    },
    // 获取状态类型
    getStatusType(status) {
      switch (status) {
        case 'success':
          return 'success';
        case 'error':
          return 'danger';
        case 'uploading':
          return 'warning';
        default:
          return 'info';
      }
    },
    // 获取状态文本
    getStatusText(status) {
      switch (status) {
        case 'success':
          return '成功';
        case 'error':
          return '失败';
        case 'uploading':
          return '上传中';
        default:
          return '待上传';
      }
    }
  }
};
</script>

<style scoped>
/* 上传容器样式 */
.upload-container {
  padding: 20px 0;
  width: 100%;
}

.upload-dragger {
  width: 100% !important;
}

.upload-dragger .el-upload {
  width: 100% !important;
}

.upload-dragger .el-upload-dragger {
  width: 100% !important;
  height: 200px;
  border: 2px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: border-color 0.2s ease;
  background-color: #fafafa;
  box-sizing: border-box;
}

.upload-dragger .el-upload-dragger:hover {
  border-color: #409EFF;
  width: 100%;
}

.upload-dragger .el-upload-dragger .el-icon-upload {
  font-size: 67px;
  color: #C0C4CC;
  margin: 40px 0 16px;
  line-height: 50px;
  width: 100%;
}

.upload-dragger .el-upload__text {
  color: #606266;
  font-size: 14px;
  text-align: center;
}

.upload-dragger .el-upload__text em {
  color: #409EFF;
  font-style: normal;
}

/* 模板下载样式 */
.template-download {
  margin-top: 15px;
  font-size: 14px;
  color: #606266;
}

.template-info {
  display: flex;
  align-items: center;
  gap: 8px;
}

.template-label {
  color: #606266;
  font-size: 14px;
}

.template-button {
  color: #409EFF;
  padding: 0;
  font-size: 14px;
  text-decoration: none;
}

.template-button:hover {
  color: #66b1ff;
}

/* 文件列表区域样式 */
.file-list-section {
  margin-top: 20px;
}

.section-title {
  margin: 0 0 10px 0;
  font-size: 16px;
  font-weight: 500;
  color: #409eff;
  border-left: 4px solid #409eff;
  padding-left: 10px;
}

.dialog-footer {
  text-align: center;
  padding-top: 20px;
}

/* 全局样式覆盖 */
::v-deep .el-upload {
  width: 100% !important;
}

::v-deep .el-upload-dragger {
  width: 100% !important;
}
</style>